package com.example.service.impl;

import com.example.algorithm.SnowflakeIdWorker;
import com.example.dto.SignRecordResult;
import com.example.entity.SignRecord;
import com.example.repository.SignRecordRepository;
import com.example.service.SignRecordService;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class SignRecordServiceImpl implements SignRecordService {

    @Autowired
    private SignRecordRepository signRecordRepository;

    @Override
    public SignRecordResult getSignRecordByUserId(String userId) {
        List<SignRecord> signRecords = signRecordRepository.getSignRecordsByUserId(userId);
        SignRecordResult result = SignRecordToString(signRecords);
        return result;
    }

    @Override
    public void signIn(String userId) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy,M");
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("d");
        Date date = new Date();
        String dateString = simpleDateFormat.format(date);
        int today = Integer.parseInt(simpleDateFormat1.format(date));
        SignRecord signRecord = signRecordRepository.getSignRecordByUserIdAndDateMonth(userId, dateString);
        if(signRecord == null){
            signRecord = new SignRecord();
            signRecord.setId(SnowflakeIdWorker.generateId()+"");
            signRecord.setUserId(userId);
            signRecord.setDateMonth(dateString);
            signRecord.setMask(0);
            signRecord.setContinueSignMonth(1);
            signRecord.setCreateAt(date);
            signRecord.setCreateBy("admin");
            signRecord.setUpdateAt(date);
            signRecord.setUpdateBy("admin");
            signRecord.setDel(false);
        }
        signRecord.setMask(signRecord.getMask() | 1 << today);
        signRecord.setUpdateBy("admin");
        signRecord.setUpdateAt(date);
        signRecordRepository.save(signRecord);
    }

    /**
     * 识别数据库里面的mask，把32位整数存储的签到日期读取出来
     * @param signRecords 用户签到的多个月的记录
     * @return 历史所有签到日期
     */
    private SignRecordResult SignRecordToString(List<SignRecord> signRecords){
        SignRecordResult signRecordResult = new SignRecordResult();
        signRecordResult.setList(new ArrayList<>());
        for (SignRecord s:signRecords
             ) {
            String[] date = s.getDateMonth().split(",");
            String days = Integer.toBinaryString(s.getMask());
            for(int i = days.length()-2, j = 1; i >=0; i --, j ++){
                if(days.charAt(i) == '1'){
                    //当天有签到，写到返回结果中
                    List<Integer>  list = new ArrayList<>();
                    list.add(0, Integer.parseInt(date[0]));
                    list.add(1, Integer.parseInt(date[1]));
                    list.add(2, j);
                    signRecordResult.getList().add(list);
                }
            }
        }
        return signRecordResult;
    }
}
